<template>
  <div class="admin-view">
    <div class="page-header">
      <div class="header-left">
        <h1 class="page-title"><i class="el-icon-setting"></i>管理员管理</h1>
        <p class="page-description">管理系统管理员账号</p>
      </div>
      <div class="header-right"><el-button type="primary" icon="el-icon-plus" @click="showAddDialog">新增管理员</el-button></div>
    </div>
    <el-card class="table-card">
      <el-table :data="tableData" style="width: 100%">
        <el-table-column prop="id" label="ID" width="80" />
        <el-table-column prop="username" label="管理员账号" />
        <el-table-column prop="privilege" label="权限" width="300">
          <template slot-scope="scope">
            <el-tag v-for="permission in getPermissionNames(scope.row.privilege)" :key="permission" size="mini" style="margin-right:5px;">{{ permission }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" />
        <el-table-column label="操作" width="160" align="center" fixed="right">
          <template slot-scope="scope">
            <div class="action-buttons">
              <el-button size="mini" type="primary" icon="el-icon-edit" @click="handleEdit(scope.row)" class="action-btn edit-btn">编辑</el-button>
              <el-button size="mini" type="danger" icon="el-icon-delete" @click="handleDelete(scope.row)" :disabled="scope.row.privilege === 1" class="action-btn delete-btn">删除</el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px">
      <el-form :model="form" :rules="rules" ref="form" label-width="100px">
        <el-form-item label="管理员账号" prop="username"><el-input v-model="form.username" placeholder="请输入管理员账号" /></el-form-item>
        <el-form-item label="密码" prop="password"><el-input v-model="form.password" type="password" placeholder="请输入密码" /></el-form-item>
        <el-form-item label="权限设置" prop="privilege">
          <el-checkbox-group v-model="privilegeList">
            <el-checkbox label="dept">系管理</el-checkbox>
            <el-checkbox label="major">专业管理</el-checkbox>
            <el-checkbox label="class">班级管理</el-checkbox>
            <el-checkbox label="student">学生管理</el-checkbox>
            <el-checkbox label="teacher">教师管理</el-checkbox>
            <el-checkbox label="course">课程管理</el-checkbox>
            <el-checkbox label="selection">选课修改</el-checkbox>
            <el-checkbox label="admin">管理员管理</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer"><el-button @click="dialogVisible=false">取消</el-button><el-button type="primary" @click="handleSubmit">确定</el-button></div>
    </el-dialog>
  </div>
</template>
<script>
import { getAdminList, saveAdmin, deleteAdmin, getAdminById } from '@/api'
export default { name:'AdminView', data(){ return { tableData:[], dialogVisible:false, dialogTitle:'添加管理员', form:{ id:-1, username:'', password:'', privilege:'' }, privilegeList:[], permissionBitValues:{ dept:1<<0, major:1<<1, class:1<<2, student:1<<3, teacher:1<<4, course:1<<5, selection:1<<6, admin:1<<7 }, permissionMap:{ dept:'系管理', major:'专业管理', class:'班级管理', student:'学生管理', teacher:'教师管理', course:'课程管理', selection:'选课修改', admin:'管理员管理' }, rules:{ username:[{ required:true, message:'请输入管理员账号', trigger:'blur'}], password:[{ validator:(rule,value,callback)=>{ if(this.form.id===-1 && !value) callback(new Error('请输入密码')); else if(value && value.length<6) callback(new Error('密码长度不能少于6位')); else callback(); }, trigger:'blur'}] } } }, mounted(){ this.loadData() }, methods:{ getPermissionNames(privilege){ if(privilege==null || privilege==='') return ['无权限']; if(typeof privilege==='number'){ const arr=this.privilegeValueToArray(privilege); return arr.length?arr.map(p=>this.permissionMap[p]||p):['无权限'] } if(typeof privilege==='string'){ if(/^\d+$/.test(privilege)){ const num=parseInt(privilege,10); const arr=this.privilegeValueToArray(num); return arr.length?arr.map(p=>this.permissionMap[p]||p):['无权限'] } const permissions=privilege.split(','); return permissions.map(p=>this.permissionMap[p]||p).filter(Boolean) } return ['无权限'] }, privilegeArrayToString(array){ return (array&&array.length>0)?array.join(','):'' }, privilegeStringToArray(str){ return (str&&typeof str==='string')?str.split(','):[] }, privilegeArrayToValue(arr){ if(!Array.isArray(arr)) return 0; return arr.reduce((sum,key)=> sum | (this.permissionBitValues[key]||0),0) }, privilegeValueToArray(val){ const result=[]; Object.keys(this.permissionBitValues).forEach(k=>{ if((val & this.permissionBitValues[k])!==0) result.push(k) }); return result }, async loadData(){ try{ const res = await getAdminList(); this.tableData = res.data || [] } catch(e){ this.$message.error('加载数据失败') } }, showAddDialog(){ this.dialogTitle='添加管理员'; this.form={ id:-1, username:'', password:'', privilege:'' }; this.privilegeList=[]; this.dialogVisible=true }, async handleEdit(row){ try{ const res = await getAdminById(row.id); this.dialogTitle='编辑管理员'; this.form={ ...res.data, password:'' }; if(typeof res.data.privilege==='number'){ this.privilegeList=this.privilegeValueToArray(res.data.privilege) } else if(typeof res.data.privilege==='string' && /^\d+$/.test(res.data.privilege)){ this.privilegeList=this.privilegeValueToArray(parseInt(res.data.privilege,10)) } else { this.privilegeList=this.privilegeStringToArray(res.data.privilege) } this.dialogVisible=true } catch(e){ this.$message.error('获取管理员信息失败') } }, handleDelete(row){ this.$confirm('确定删除该管理员吗?','提示',{confirmButtonText:'确定',cancelButtonText:'取消',type:'warning'}).then(async()=>{ try{ await deleteAdmin(row.id); this.$message.success('删除成功'); this.loadData() }catch(e){ this.$message.error('删除失败') } }) }, async handleSubmit(){ this.$refs.form.validate(async valid=>{ if(valid){ try{ const privilegeValue=this.privilegeArrayToValue(this.privilegeList); const privilegeString=this.privilegeArrayToString(this.privilegeList); const submitData={ id:this.form.id, username:this.form.username, privilege:privilegeValue, privilegeString }; if(this.form.id===-1){ submitData.password=this.form.password } else if(this.form.password && this.form.password.trim()!==''){ submitData.password=this.form.password } await saveAdmin(submitData); this.$message.success(this.form.id===-1?'添加成功':'编辑成功'); this.dialogVisible=false; this.loadData() }catch(e){ const msg = e.response?.data?.message || e.response?.data?.error || e.message; this.$message.error('保存管理员失败: '+ msg) } } }) } } }
</script>
<style scoped>
.admin-view{ padding:24px; min-height:calc(100vh - 120px); background:#f5f6fa; }
.page-header{ display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:24px; background:white; padding:24px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.1); border:1px solid #e8e9ea; }
.header-left{ flex:1; }
.page-title{ margin:0 0 8px 0; font-size:28px; font-weight:700; color:#1a1a1a; display:flex; align-items:center; }
.page-title i{ margin-right:12px; color:#409eff; font-size:32px; }
.page-description{ margin:0; color:#6c757d; font-size:15px; font-weight:400; }
.header-right{ display:flex; align-items:center; }
.table-card{ margin-bottom:20px; }
.action-buttons{ display:flex; gap:8px; justify-content:center; align-items:center; }
:deep(.action-btn){ width:60px!important; height:28px!important; padding:0!important; border-radius:4px!important; font-size:12px!important; display:flex!important; align-items:center!important; justify-content:center!important; min-width:60px!important; }
:deep(.edit-btn){ background-color:#409eff!important; border-color:#409eff!important; color:white!important; }
:deep(.edit-btn:hover){ background-color:#66b1ff!important; border-color:#66b1ff!important; }
:deep(.delete-btn){ background-color:#f56c6c!important; border-color:#f56c6c!important; color:white!important; }
:deep(.delete-btn:hover){ background-color:#f78989!important; border-color:#f78989!important; }
:deep(.delete-btn:disabled){ background-color:#c0c4cc!important; border-color:#c0c4cc!important; color:white!important; }
</style>
